package org.practice.chart;

import java.io.StringWriter;
import java.lang.reflect.Field;
import java.util.*;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

/**
 * 数据转换工具：奂责将相应的图表转换成XML字符串
 * 下面的XML是根据相应的对象来拼装，比如：柱状图的xml就应该用柱状图对象来拼装
 * @author jack
 */
public class DataTransferUtil {
    //下面的XML是根据相应的对象来拼装，比如：柱状图的xml就应该用柱状图对象来拼装，图表对象都是些简单属性
    public static String getChartsTitleXml(FusionChart chart){
        StringBuffer xml=new StringBuffer("<graph ");
        Field[] fields=DataTransferUtil.getClassFields(chart.getClass().getName());
        System.out.println("getChartsTitleXml fields length===="+fields.length);
        for(Field field:fields){
            System.out.println("=="+field.getName());
        }
        for (Field field : fields) {
            field.setAccessible(true);//设置访问私有的属性
            try {
                if (chart!=null&&!"dataMap".equals(field.getName())) {
                    Object c=field.get(chart);
                    xml.append(field.getName()).append("='").append(c!=null?c.toString():"").append("' ");
                }
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return xml.append(">").toString();
    }

    /**
     * 修改对象的属性对象的属性(Map)
     * @param chart
     */
    public static void changeChartProp(FusionChart chart,Map<String,String> values){
        Set<Map.Entry<String,String>> entry=values.entrySet();
        Field[] fields=DataTransferUtil.getClassFields(chart.getClass().getName());
        System.out.println("changeChartProp fields length===="+fields.length);
        for (Field field : fields) {
            field.setAccessible(true);//设置访问私有的属性(取值或赋值)
            for (Iterator<Map.Entry<String, String>> iterator = entry.iterator(); iterator.hasNext(); ) {
                Map.Entry<String, String> next = (Map.Entry<String, String>) iterator.next();
                try {
                    if(chart!=null&&next.getKey().equals(field.getName())){
                        field.set(chart,next.getValue());
                    }
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }

        }
    }

    /**
     * 修改对象的属性对象的属性(prop="key1=value1,key2=value2....")
     * @param chart
     */
    public static void changeChartProp(FusionChart chart,String prop){
        StringTokenizer st=null;
        if(prop.contains(",")){
            st= new StringTokenizer(prop,",");
        }else{
            st= new StringTokenizer(prop);
        }
        List<String> props=new ArrayList<String>();
        while(st.hasMoreTokens()){
            String rs=st.nextToken();
            props.add(rs);
        }
        Field[] fields=DataTransferUtil.getClassFields(chart.getClass().getName());
        System.out.println("changeChartProp fields length===="+fields.length);
        for (Field field : fields) {
            field.setAccessible(true);//设置访问私有的属性(取值或赋值)
            for (Iterator<String> iterator = props.iterator(); iterator.hasNext(); ) {
                String[] next = iterator.next().split("=");
                try {
                    if(chart!=null&&next[0].equals(field.getName())){
                        field.set(chart,next[1]);
                    }
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }

        }
    }

    public static String getChartsCategoriesXml(String[] categories,String props){
        StringBuffer xml=new StringBuffer("<categories "+props+">");
        for(String categoryName:categories){
            xml.append("<category ").append(" name='").append(categoryName).append("' />");
        }
        xml.append("</categories>");
        return xml.toString();
    }

    public static String getChartsDatasetXml(Map<String,String[]> dataMap,String[] colors){

        StringBuffer xml=new StringBuffer();
        String[] categories = null;
        String[] links=null;
        if(dataMap.containsKey("categories")){
            categories=dataMap.remove("categories");
        }
        if(dataMap.containsKey("link")){
            links=dataMap.remove("link");
        }
        int varible=0;
        for (Iterator<String> iterator = dataMap.keySet().iterator(); iterator.hasNext(); ) {
            /*String color="";
            switch (varible){
                case 0:color="00FF00";break;//绿
                case 1:color="FFFF00";break;//黄
                default:color="FF0000";//红
            }
            link='javascript:showPieChart(\""+str[8]+"\",\""+dd+"\");'
            <set").append(" link='javascript:showPieChart(\""+str[8]+"\",\""+dd+"\");' value=").append("'"+v1.substring(0, v1.length()-1)+"'").append(" />
            */
            String key =  iterator.next();
            String[] data=null;
            xml.append("<dataset seriesname='").append(key).append("' color='").append(colors[varible]).append("' >");

            for (int i = 0; i < (data=dataMap.get(key)).length; i++) {
                xml.append("<set value='").append(data[i]).append("' ");
                if(links!=null&&links.length>0){
                    xml.append(" link='").append(links[i]).append("' ");
                }
                xml.append(" />");
            }
            xml.append("</dataset>");
            varible++;
        }
        return xml.toString();
    }

    public static String getChartsSetXml(Map<String,String[]> dataMap){
        StringBuffer xml=new StringBuffer();
        String[] properties=dataMap.remove("setProperties");
        String[] links=null;
        if(dataMap.containsKey("link")){
            links=dataMap.remove("link");
        }
        int varible=0;
        for (String prop: properties) {
            xml.append("<set "+prop);
            if(links!=null&&links.length>0){
                xml.append(" link='").append(links[varible]).append("' ");
            }
            xml.append(" />");
            varible++;
        }
        return xml.toString();
    }
    /**
     * 根据传入的类名返回对象所有属性的数组
     * @return
     */
    private static Field[] getClassFields(String className) {
        Class<?> c = null;
        try {
            c = Class.forName(className);
        } catch (ClassNotFoundException e) {
            System.out.println("类没找到！");
            e.printStackTrace();
        }
        Field[] fields1 = c.getDeclaredFields();//获得本类定义的所有属性(包括私有)，不获得父类继承的属性
        Field[] fields2 =FusionChart.class.getDeclaredFields();//获得父类中定义的属性
        return  mergeArray(fields1,fields2);
    }

    /**
     * 合并两个数组，得到当前图表的所有属性
     * @param fields1
     * @param fields2
     * @return
     */
    private static Field[] mergeArray(Field[] fields1,Field[] fields2){
        List<Field> list=new ArrayList<Field>();
//        for (int i = 0; i < fields1.length; i++) {
//            list.add(fields1[i]);
//        }
        list.addAll(Arrays.asList(fields1));
        for (int i = 0; i < fields2.length; i++) {
            if (list.indexOf(fields2[i])==-1) {
                list.add(fields2[i]);
            }
        }
        return list.toArray(new Field[list.size()]);
    }
    /**
     * 使用DOM4J的漂亮格式缩进打印xml字符串
     * @param xml
     */
    public static void printLayoutString(String xml){
        try {
            Document doc = DocumentHelper.parseText(xml);
            //输出格式化器
            OutputFormat format = OutputFormat.createPrettyPrint();
            format.setEncoding("UTF-8");    // 指定XML编码
            format.setNewlines(true);
            format.setIndent(true);
            StringWriter out = new StringWriter();//String输出流，默认目标是内存空间
            //FileOutputStream fos=new FileOutputStream(filename);//默认目标是磁盘文件
            XMLWriter xmlWriter = new XMLWriter(out, format);
            xmlWriter.write(doc);
            xmlWriter.flush();
            String s = out.toString();
            System.out.println(s);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}
